﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;

namespace Deloitte.Data
{
    public class DataRowToObjectMapper<T>
    {
        private List<DataColumnToObjectPropertyMap<T>> _invalidMaps;

        public List<DataColumnToObjectPropertyMap<T>> InvalidMaps
        {
            get { return _invalidMaps; }
            set { _invalidMaps = value; }
        }
        private List<DataColumnToObjectPropertyMap<T>> _columnMaps;

        public List<DataColumnToObjectPropertyMap<T>> ColumnMaps
        {
            get { return _columnMaps; }
            set { _columnMaps = value; }
        }        
        
        public DataRowToObjectMapper(List<DataColumnToObjectPropertyMap<T>> dataColumnMaps)
        {
            _columnMaps = dataColumnMaps;                
        }

        public bool IsValidMap(DataTable table)
        {
            PropertyInfo info;
            InvalidMaps = new List<DataColumnToObjectPropertyMap<T>>();
            bool isValid = false;
            foreach (DataColumnToObjectPropertyMap<T> map in ColumnMaps)
            {
                try
                {
                    if (table.Columns.Contains(map.DataRowColumnName) == false)
                    {
                        isValid = false;
                        InvalidMaps.Add(map);
                    }
                    info = (typeof(T).GetProperty(map.PropertyName));                    
                }
                catch (Exception)
                {
                    isValid = false;
                    InvalidMaps.Add(map);
                }
            }
            return isValid;
        }

        public T MapDataRow(DataRow row)
        {
            T myObject = Deloitte.Generics<T>.GetNewObject<T>();
            foreach (DataColumnToObjectPropertyMap<T> map in ColumnMaps)
            {
                try
                {
                    if (row[map.DataRowColumnName] != DBNull.Value)
                    {
                        if (myObject.GetType().GetProperty(map.PropertyName).PropertyType.FullName == typeof(string).FullName) myObject.GetType().GetProperty(map.PropertyName).SetValue(myObject, row[map.DataRowColumnName].ToString(), null);
                        else if (myObject.GetType().GetProperty(map.PropertyName).PropertyType.FullName == typeof(short).FullName) myObject.GetType().GetProperty(map.PropertyName).SetValue(myObject, System.Convert.ToInt16(row[map.DataRowColumnName]), null);
                        else if (myObject.GetType().GetProperty(map.PropertyName).PropertyType.FullName == typeof(int).FullName) myObject.GetType().GetProperty(map.PropertyName).SetValue(myObject, System.Convert.ToInt32(row[map.DataRowColumnName]), null);
                        else myObject.GetType().GetProperty(map.PropertyName).SetValue(myObject, row[map.DataRowColumnName], null);
                    }
                    else
                    {
                        if (myObject.GetType().GetProperty(map.PropertyName).PropertyType == typeof(string).GetType())
                        {
                            myObject.GetType().GetProperty(map.PropertyName).SetValue(myObject, string.Empty, null);
                        }
                    }
                }
                catch(Exception e){}
            }
            return myObject;
        }
    }
}
